10 * 1024 * 1024) { // 10MB limit
$error = "File size too large. Maximum allowed size is 10MB.";
} else {
try {
$inputFileName = $_FILES['excel_file']['tmp_name'];
if ($use_phpspreadsheet) {
// Use PhpSpreadsheet
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
if ($file_extension === 'xls') {
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
}
// Set encoding to handle special characters
$reader->setReadDataOnly(true);
$reader->setReadEmptyCells(false);
$spreadsheet = $reader->load($inputFileName);
$sheet = $spreadsheet->getActiveSheet();
$highestRow = $sheet->getHighestRow();
} else {
// Fallback to manual CSV parsing if no library available
$error = "PhpSpreadsheet library not found. Please install it via Composer or use the manual CSV upload method.";
throw new Exception($error);
}
$pdo->beginTransaction();
// Set connection encoding to UTF-8 to handle special characters
$pdo->exec("SET NAMES utf8mb4");
$questions_added = 0;
$skipped_rows = 0;
for ($row = 2; $row <= $highestRow; $row++) {
if ($use_phpspreadsheet) {
$question_text = $sheet->getCell('B' . $row)->getValue();
$option_a = $sheet->getCell('C' . $row)->getValue();
$option_b = $sheet->getCell('D' . $row)->getValue();
$option_c = $sheet->getCell('E' . $row)->getValue();
$option_d = $sheet->getCell('F' . $row)->getValue();
$correct_answer = strtoupper(trim($sheet->getCell('G' . $row)->getValue()));
$marks = $sheet->getCell('H' . $row)->getValue() ?: 1;
}
// Skip empty rows
if (empty(trim($question_text))) {
$skipped_rows++;
continue;
}
// Validate correct answer
if (!in_array($correct_answer, ['A', 'B', 'C', 'D'])) {
$error = "Invalid correct answer '{$correct_answer}' in row {$row}. Must be A, B, C, or D.";
$pdo->rollBack();
break;
}
// Validate marks
$marks = intval($marks);
if ($marks < 1) {
$marks = 1;
}
// Clean and prepare text data for UTF-8 encoding
$clean_question_text = trim($question_text);
$clean_option_a = trim($option_a);
$clean_option_b = trim($option_b);
$clean_option_c = trim($option_c);
$clean_option_d = trim($option_d);
// Replace problematic characters with their UTF-8 equivalents
$clean_question_text = preg_replace('/\xE2\x88\x92/', '-', $clean_question_text); // Replace minus sign
$clean_question_text = mb_convert_encoding($clean_question_text, 'UTF-8', 'UTF-8');
$clean_option_a = preg_replace('/\xE2\x88\x92/', '-', $clean_option_a);
$clean_option_a = mb_convert_encoding($clean_option_a, 'UTF-8', 'UTF-8');
$clean_option_b = preg_replace('/\xE2\x88\x92/', '-', $clean_option_b);
$clean_option_b = mb_convert_encoding($clean_option_b, 'UTF-8', 'UTF-8');
$clean_option_c = preg_replace('/\xE2\x88\x92/', '-', $clean_option_c);
$clean_option_c = mb_convert_encoding($clean_option_c, 'UTF-8', 'UTF-8');
$clean_option_d = preg_replace('/\xE2\x88\x92/', '-', $clean_option_d);
$clean_option_d = mb_convert_encoding($clean_option_d, 'UTF-8', 'UTF-8');
// Insert question with subject_id
$stmt = $pdo->prepare("INSERT INTO questions (exam_id, subject_id, question_text, option_a, option_b, option_c, option_d, correct_answer, marks) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->execute([
$exam_id,
$subject_id,
$clean_question_text,
$clean_option_a,
$clean_option_b,
$clean_option_c,
$clean_option_d,
$correct_answer,
$marks
]);
$questions_added++;
}
if (empty($error)) {
// Update exam question count
$stmt = $pdo->prepare("UPDATE exams SET total_questions = (SELECT COUNT(*) FROM questions WHERE exam_id = ?) WHERE id = ?");
$stmt->execute([$exam_id, $exam_id]);
$pdo->commit();
$success = "Successfully uploaded {$questions_added} questions for the selected subject!" . ($skipped_rows > 0 ? " {$skipped_rows} empty rows were skipped." : "");
}
} catch (Exception $e) {
$pdo->rollBack();
$error = "Error uploading file: " . $e->getMessage();
}
}
}
}
// Get exams for dropdown
$stmt = $pdo->prepare("SELECT * FROM exams ORDER BY year DESC, name");
$stmt->execute();
$exams = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Get subjects for dropdown
$stmt = $pdo->prepare("SELECT * FROM subjects ORDER BY name");
$stmt->execute();
$subjects = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
Upload Questions - Admin
Upload Questions
Bulk upload questions from Excel files
Note: PhpSpreadsheet library not detected. Please install it using Composer:
composer require phpoffice/phpspreadsheet
Alternatively, you can manually parse CSV files or contact your system administrator.
Upload Excel File
Excel File Format
Your Excel file should have the following columns in order (starting from row 2):